package org.adream.account.aop.aspect;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * 此类为一个切面类，主要作用就是对接口的请求进行拦截
 * 拦截的方式，只需要在指定接口方法上面加上@MonitorRequest注解即可
 *
 */
@Aspect
@Component 
public class RequestAspect {
	
	private final static Logger logger = LoggerFactory.getLogger(RequestAspect.class);
	
	@Pointcut("@annotation(org.adream.account.aop.annotation.MonitorRequest)")
	public void controllerAspect(){}
	 
	/**
     * 表示在执行被@MonitorRequest注解修饰的方法之前 会执行doBefore()方法
     *
     * @param joinPoint 连接点，就是被拦截点
     */
    @Before("controllerAspect()")
    public void doBefore(JoinPoint joinPoint) {
    	 //获取到请求的属性
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        
        HttpServletRequest request = attributes.getRequest();
        HttpServletResponse response = attributes.getResponse();
        
        //URL：根据请求对象拿到访问的地址 
        String url =  request.getRequestURI();
        String queryString = request.getQueryString();
        if(!StringUtils.isEmpty(queryString)) {
        	url = url + "?" + queryString;
        }
        try {
			url = URLEncoder.encode(url,"utf-8");
		} catch (UnsupportedEncodingException e1) {
			logger.debug("url 编码错误");
			url = null;
		}
        if(StringUtils.isEmpty(url)) {
        	url = "/account/aopLogin";
        }else {
        	url = "/account/aopLogin?url="+ url;
        }
        //二次登陆时间戳
        Object loginTime = request.getSession().getAttribute("aopLoginTime");
        if(loginTime == null) {
        	try {
				response.sendRedirect(url);
			} catch (IOException e) {
				logger.debug("二次登陆转发错误");
			}
        	return;
        } else {
        	Long now = new Date().getTime();
        	Long t = 0l ;
        	try{
        		t = Long.parseLong(String.valueOf(loginTime));
    		}catch(NumberFormatException e){
    			logger.debug("时间戳转换错误");
    			return;
    		}
        	if(Math.abs(now-t)>(60 * 60 * 1000)) {
        		//60分钟超时 重新验证
        		try {
    				response.sendRedirect(url);
    			} catch (IOException e) {
    				logger.debug("二次登陆转发错误!");
    			}
            	return;
        	} else {
        		//正常 刷新时间戳
        		request.getSession().setAttribute("aopLoginTime", new Date().getTime());
        	}
		}
    }
}